package day04;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author chenshijie
 * @date 2023/12/15 14:51
 */

public class NettyClientOther {
    static int MAX_RETRY = 2;
    public static void main(String[] args) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        bootstrap
                // 1. 指定线程模型
                .group(group)
                // 2. 指定IO类型为NIO
                .channel(NioSocketChannel.class)
                // 3. IO处理逻辑
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        System.out.println(ch.attr(AttributeKey.valueOf("clientName")).get());
                        ch.pipeline().addLast(new StringEncoder());

                    }
                })
                .attr(AttributeKey.newInstance("clientName"), "nettyClient")
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
                .option(ChannelOption.SO_KEEPALIVE, true);


        try {

            connect(bootstrap, "127.0.0.1", 8001, MAX_RETRY);


//            while (true) {
//                System.out.println(1);
//                if (future.isSuccess()) {
//                    System.out.println(future.isSuccess());
//                    future.channel().writeAndFlush(new Date() + ": hello world!");
//                    Thread.sleep(2000);
//
//                }
//            }


        } catch (Exception e) {

            e.printStackTrace();
            System.out.println("异常为" + e.getMessage());
        }

    }

    private static void connect(Bootstrap bootstrap, String host, int port, int retry){
        GenericFutureListener<Future<? super Void>> futureListener = new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("连接成功！");
                    

                } else if (retry == 0) {
                    System.err.println("重试次数过多，放弃连接！");
                    bootstrap.config().group().shutdownGracefully();


                } else {
                    int order = (MAX_RETRY - retry) + 1;
                    // 重连间隔
                    int delay = 1 << order;
                    System.err.println(new Date() + "：连接失败，第" + order + "次重连......");

                    bootstrap.config().group().schedule(() -> connect(bootstrap, host, port, retry - 1), delay, TimeUnit.SECONDS);

                }
            }
        };


        ChannelFuture channelFuture = bootstrap
                .connect(host, port)
                .addListener(futureListener);

    }
}
